﻿using System;
using System.Reflection;
using Needle.Core.Reflection;
using Needle.Framework;
using Needle.Utils;

namespace Needle.Core.Factory
{
    /// <summary>
    /// provides a base implementation of IFactory
    /// </summary>
    public class FactoryBase : Component, IFactory
    {
        /// <summary></summary>
        [Obsolete("Use the other constructor, this one is for designer support only")]
        public FactoryBase()
        { }
        /// <summary></summary>
        public FactoryBase(Type producedType)
        {
            Ensure.NotNull(producedType, "producedType");
            _ProducedType = producedType;
        }
        
        private Type _ProducedType;
        /// <summary></summary>
        public Type ProducedType
        {
            get { return _ProducedType; }
        }

        #region IFactory Members

        /// <summary>
        /// Creates an instance of concrete type t with the supplied parameters.
        /// </summary>
        public virtual object CreateInstance(  params object[] args)
        {
            ConstructorInfo[] ctors = ProducedType.GetConstructors();
            foreach (ConstructorInfo ctor in ctors)
            {
                if (ctor.CanAccept(args))
                    return ctor.Invoke(args);
            }
            throw new NotSupportedException();
        }
         
        /// <summary>
        /// Generic wrapper for CreateInstance(Type t, params object[] args)
        /// </summary>
        public T CreateInstance<T>(params object[] args)
        {
            return (T)CreateInstance(args);
        }

        #endregion

    }
}
